package developer.算法.链表.相交链表;

import java.util.Objects;

/**
 * 1 2 3 4 5 n 2 3 4 5
 * 2 3 4 5 n 1 2 3 4 5
 *
 * @author zhangyongkang
 * @time 2024/6/11 16:16
 * @description https://leetcode.cn/problems/intersection-of-two-linked-lists/description/?envType=study-plan-v2&envId=top-100-liked
 * 给你两个单链表的头节点 headA 和 headB ，请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点，返回 null 。
 * <p>
 * 图示两个链表在节点 c1 开始相交：
 * <p>
 * <p>
 * <p>
 * 题目数据 保证 整个链式结构中不存在环。
 * <p>
 * 注意，函数返回结果后，链表必须 保持其原始结构 。
 * <p>
 * 自定义评测：
 * <p>
 * 评测系统 的输入如下（你设计的程序 不适用 此输入）：
 * <p>
 * intersectVal - 相交的起始节点的值。如果不存在相交节点，这一值为 0
 * listA - 第一个链表
 * listB - 第二个链表
 * skipA - 在 listA 中（从头节点开始）跳到交叉节点的节点数
 * skipB - 在 listB 中（从头节点开始）跳到交叉节点的节点数
 * 评测系统将根据这些输入创建链式数据结构，并将两个头节点 headA 和 headB 传递给你的程序。如果程序能够正确返回相交节点，那么你的解决方案将被 视作正确答案 。
 */
public class Solution_self {

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     * int val;
     * ListNode next;
     * ListNode(int x) {
     * val = x;
     * next = null;
     * }
     * }
     */
    public class Solution {
        /**
         * 该题的核心是如何将两个链条在最后面对齐，
         * 1 2 3 4 5 6 n 8 9 0 7 7 4 5 6
         * 8 9 0 7 7 4 5 6 n 1 2 3 4 5 6
         * 例如入参a:[1,2,3,4,5,6] b:[4,5,6,]
         * pA的路线：1,2,3,4,5,6,null,4,5,6
         * pB的路线：4,5,6,null,1,2,3,4,5,6
         * 这样遍历的话就可以巧妙的将 尾部进行对其
         *
         * @param headA
         * @param headB
         * @return
         */
        public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
            if (Objects.isNull(headA)) return null;
            if (Objects.isNull(headB)) return null;
            ListNode pA = headA;
            ListNode pB = headB;
            while (pA != pB) {//停止条件  PA=PB ==null
                pA = pA == null ? headB : pA.next;
                pB = pB == null ? headA : pB.next;
            }
            return pA;
        }
    }


    public class ListNode {
        int val;
        ListNode next;

        ListNode(int x) {
            val = x;
            next = null;
        }
    }

}
